#![no_std]
#![feature(abi_x86_interrupt)]
#![feature(alloc_error_handler)]
#![feature(allocator_api)]
#![feature(int_roundings)]
#![feature(naked_functions)]
#![feature(ptr_internals)]
#![feature(string_remove_matches)]
#![allow(internal_features)]
#![allow(static_mut_refs)]

extern crate alloc;

pub mod acpi;
pub mod context;
pub mod cpu;
pub mod display;
pub mod irq;
pub mod klog;
pub mod memory;
pub mod scheme;
pub mod serial;
pub mod syscall;
pub mod terminal;
mod unwind;

pub fn init() {
    memory::init_heap();
    klog::init();

    log::info!("VMOS Starting...");

    cpu::smp::CPUS.write().init_bsp();
    irq::irq::IDT.load();
    cpu::smp::CPUS.write().init_ap();
    irq::apic::init();
    irq::irq::init();
    scheme::init();
    syscall::init();
    context::init();
}

pub fn addr_of<T>(reffer: &T) -> usize {
    reffer as *const T as usize
}

pub fn ref_to_mut<T>(reffer: &T) -> &mut T {
    unsafe { &mut *(addr_of(reffer) as *const T as *mut T) }
}
